/*
============================================================================
 Name        : AudioRecorder.cpp
 Author      : DANG Zhengfa
 Version     :
 Copyright   : Zhengfa Company Limited
 Description : CAudioRecorder implementation
============================================================================
*/

#include "AudioRecorder.h"
#include "Log.h"
#include "Utilities.h"
#include "Window.h"

#include <MdaAudioSampleEditor.h> // For CMdaAudioRecorderUtility, Link against: MediaClientAudio.lib

CAudioRecorder::CAudioRecorder()
{
	// No implementation required
}


CAudioRecorder::~CAudioRecorder()
{
	if( iState == ERecording )  //stop recording, and close
	{
		iRecorder->Stop();
		iRecorder->Close();
	}
	else if( iState == EOpen)  // close file
		iRecorder->Close();

	if(iRecorder)
		delete iRecorder;
	
	if(iClient)
		delete iClient;
}

CAudioRecorder* CAudioRecorder::NewLC()
{
	CAudioRecorder* self = new (ELeave)CAudioRecorder();
	CleanupStack::PushL(self);
	self->ConstructL();
	return self;
}

CAudioRecorder* CAudioRecorder::NewL()
{
	CAudioRecorder* self=CAudioRecorder::NewLC();
	CleanupStack::Pop(); // self;
	return self;
}

void CAudioRecorder::ConstructL()
{
	iRecorder = CMdaAudioRecorderUtility::NewL(*this);
	// How can I get the speech stream during the phone-call
	// the problem is that you need to set the priority to 80, in you recorder
	iRecorder->SetPriority(80,EMdaPriorityPreferenceTime);
	
	iClientRect.SetRect(137,8,150,21);
	iState = ENotReady;
}

void CAudioRecorder::MoscoStateChangeEvent(CBase* aObject, TInt aPreviousState, TInt aCurrentState, TInt aErrorCode)
{
	TRAPD (err, MoscoStateChangeEventL(aObject, aPreviousState, aCurrentState, aErrorCode))
	if ( err )
	{
		StopRecord();
	}
}

void CAudioRecorder::MoscoStateChangeEventL(CBase* aObject, TInt aPreviousState, TInt aCurrentState, TInt aErrorCode)
{
	PrintString16(_L("Recorder:MoscoStateChangeEventL ..."));
	PrintNumber(aPreviousState);
	PrintNumber(aCurrentState);
	PrintNumber(aErrorCode);

	 //if the recording has died, this means that the recording should be finished;
	 //  should only happen when recording on the telephony line
	if( aErrorCode == KErrDied && iState == ERecording )  // error,
	{
		PrintString16(_L("KErrDied, stop recording ..."));
		StopRecord();
		return;
	}

	// no error, do our action
	if( aObject == iRecorder )
	{
		switch(aCurrentState)
		{
		case CMdaAudioRecorderUtility::ENotReady:
			PrintString16(_L("ENotReady ..."));
			iState = ENotReady;
			break;

		case CMdaAudioRecorderUtility::EOpen:
			PrintString16(_L("EOpen ..."));
			// we will start recording ...

			// set settings for recording.
			iRecorder->SetAudioDeviceMode(CMdaAudioRecorderUtility::ETelephonyOrLocal);
			iRecorder->SetGain( iRecorder->MaxGain() );

			// other possible setting;
			//iRecorder->SetDestinationBitRateL();
			//iRecorder->SetDestinationDataTypeL();
			//iRecorder->SetDestinationFormatL();
			//iRecorder->SetDestinationNumberOfChannelsL();
			//iRecorder->SetDestinationSampleRateL();

			// Delete current audio sample from beginning of file
			//iRecorder->SetPosition(TTimeIntervalMicroSeconds(0));
			//iRecorder->CropL();

			// start recording
			PrintString16(_L("Begin to RecordL() ..."));
			iRecorder->RecordL();

			iState = EOpen;
			break;

		case CMdaAudioRecorderUtility::ERecording:
			PrintString16(_L("ERecording ..."));
			iState = ERecording;
			break;

		case CMdaAudioRecorderUtility::EPlaying:
			iState = EPlaying;
			break;
		default:
			break;
		}
	}
}


void CAudioRecorder::RecordMessageL(TBool aIsLocal)
{
	PrintString16(_L("Recorder:RecordMessageL ..."));
	// aIsLocal is not used now
	PrintNumber(aIsLocal);

	TFileName fn;
	GetUniqueAudioPath(fn);
	PrintString16(fn);
	
	// open file , when it is ready, MoscoStateChangeEvent will be called
	// settings will be done automatically according to file extension
	//   here we use "amr"
	iRecorder->OpenFileL(fn);
	iState = EInit;
	
	// create hint window
	if(iClient)
	{
		delete iClient;
		iClient = NULL;
	}
	iClient = CWsClient::NewL(iClientRect);
}

void CAudioRecorder::StopRecord()
{
	PrintString16(_L("Recorder:Stop recording!"));

	if( iState == ERecording )
	{
		iRecorder->Stop();
		iRecorder->Close();
	}
	else if( iState == EOpen )
	{
		iRecorder->Close();
	}
	iState = ENotReady;

	// delete hint windows
	delete iClient;
	iClient = NULL;
}

TBool CAudioRecorder::IsRecording()
{
	if( iState == EInit || iState == EOpen || iState == ERecording )
		return ETrue;
	return EFalse;
}


